﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.CommandBars;
using EnvDTE;
using System.IO;
using System.Xml;
using System.Windows.Forms;
using System.Xml.Linq;
using VS4CRM.Lib;

namespace VS4CRM.AddIn.Commands
{
	public class ExportCommand: CommandBase
	{
        XDocument _exportData;


        #region constructor & descructor

		public ExportCommand(DTEHandler dteHandler, ScriptUploader uploader)
			: base(dteHandler, uploader)
        {
        }

        #endregion

        #region public methods


        public static ExportCommand Create(DTEHandler dteHandler, bool beginGroup, CommandBar[] commandbars, ScriptUploader uploader)
        {
			ExportCommand instance = new ExportCommand(dteHandler, uploader);
            instance.CommandInstance = dteHandler.Menu.CreateCommand(
                "EXPORTSELECTED", 
                "&Export To CRM", 
                "Exports Selected Items To CRM", 
                "Global::Ctrl+Shift+Alt+B,b", 
                new ExecuteDelegate(instance.Execute),
                new StatusDelegate(instance.Status));

            dteHandler.Menu.AddToCommandBars(instance.CommandInstance, beginGroup, commandbars);

            return instance;
        }

		internal void Export(ProjectItem entityItem)
		{
			EnvDTE.StatusBar statusBar = DTEInstance.Application.StatusBar;
			if ((new DirectoryInfo(entityItem.get_FileNames(1)).Exists))
			{
				//folder
				foreach (ProjectItem pItem in entityItem.ProjectItems)
				{
					try
					{
						Export(pItem);
					}
					catch (Exception ex)
					{
						if (entityItem != null)
						{
							string fileName = entityItem.get_FileNames(1);

							this.DTEInstance.ApplicationOutputWindow.ActivePane.OutputTaskItemString(
								"Export Error", vsTaskPriority.vsTaskPriorityHigh, "Export Error", vsTaskIcon.vsTaskIconCompile,
								fileName, 0, ex.Message, true);

						}
					}
				}
			}
			else
			{
				string extension = entityItem.Properties.Item("Extension").Value.ToString();
				if (extension == ".js")
				{
						
					if (entityItem.Document != null && entityItem.IsDirty && !entityItem.Saved)
					{
						entityItem.Save(null);
						
					}

					HandleScriptChanges(entityItem);
					
					ProjectItem parentEntity = entityItem.Collection.Parent as ProjectItem;
					if (parentEntity != null)
					{
					bool result = _uploader.AppendToCustomizations(parentEntity.get_FileNames(1));
						//bool result = _uploader.UploadCustomizationToCRM(parentEntity.get_FileNames(1), false);
					}
				}
				else if (extension == ".xml")
				{
					foreach (ProjectItem actoinItem in entityItem.ProjectItems)
					{
						try
						{
							if (actoinItem.Document != null && actoinItem.IsDirty && !actoinItem.Saved)
							{
								actoinItem.Save(null);
							}
							HandleScriptChanges(actoinItem);
						}
						catch (Exception ex)
						{
							this.DTEInstance.ApplicationOutputWindow.ActivePane.OutputString("Export Error: " + ex.Message);
							statusBar.Text = "Not All customisations were uploaded!";
						}
					}
					string fileName = entityItem.get_FileNames(1);

					if (!entityItem.Saved)
						entityItem.Save(fileName);
					
					//_uploader.UploadCustomizationToCRM(fileName, false);
					bool result = _uploader.AppendToCustomizations(fileName);
					string name = entityItem.Name;
				}
			}
		}

        internal override void Execute()
        {
			EnvDTE.StatusBar statusBar = DTEInstance.Application.StatusBar;
			statusBar.Text = "Export to CRM in Progress";
			int errorCount = 0;
			_exportData = new XDocument();

			try
			{
				SelectedItems selectedItems = DTEInstance.AddInInstance.DTE.SelectedItems;
				foreach (SelectedItem item in selectedItems)
				{
					
					ProjectItem entityItem = null;
					try
					{

						if (item.Project != null)
						{
							foreach (ProjectItem pItem in item.Project.ProjectItems)
							{
								try
								{
									Export(pItem);
								}
								catch (Exception ex)
								{
									if (entityItem != null)
									{
										string fileName = entityItem.get_FileNames(1);

										this.DTEInstance.ApplicationOutputWindow.ActivePane.OutputTaskItemString(
											"Export Error", vsTaskPriority.vsTaskPriorityHigh, "Export Error", vsTaskIcon.vsTaskIconCompile,
											fileName, 0, ex.Message, true);

										errorCount++;
									}
								}
							}
						}
						else
						{
							Export(item.ProjectItem);
						}
					}
					catch (Exception ex)
					{
						if (entityItem != null)
						{
							string fileName = entityItem.get_FileNames(1);

							this.DTEInstance.ApplicationOutputWindow.ActivePane.OutputTaskItemString(
								"Export Error", vsTaskPriority.vsTaskPriorityHigh, "Export Error", vsTaskIcon.vsTaskIconCompile,
								fileName, 0, ex.Message, true);

							errorCount++;
						}
					}
				}
				_uploader.PushCustomizations(false);
				_uploader.Customization.PublishAll();
				
				if (errorCount > 0)
				{
					statusBar.Text = String.Format("Export to CRM Completed with {0} errors.",errorCount);
				}
				else
					statusBar.Text = "Export to CRM Completed.";
			}
			catch (Exception ex)
			{
				this.DTEInstance.ApplicationOutputWindow.ActivePane.OutputString("Export Error: " + ex.Message);
				statusBar.Text = "Export to CRM Failed!";
				throw ex;
			}
        }
		private void HandleScriptChanges(ProjectItem projectItem)
		{
		SourceControl sourceControl = DTEInstance.Application.SourceControl;

		if (!sourceControl.IsItemCheckedOut(projectItem.get_FileNames(1)))
				return;
		
			if (projectItem.Collection.Count == 2 && projectItem.Name.EndsWith(".xml.onload.js") || projectItem.Name.EndsWith(".xml.onsave.js"))
			{
				string[] filename = projectItem.Name.Split(new char[1] { '.' });
				string entityFileName = (projectItem.Collection.Parent as ProjectItem).get_FileNames(1);
				FileInfo fi = new FileInfo(entityFileName);
				if (fi.Exists)
				{
					XmlDocument doc = new XmlDocument();
					doc.XmlResolver = null;
					doc.Load(fi.FullName);

					string scriptText = File.ReadAllText(projectItem.get_FileNames(1));

					bool retVal = _uploader.SetCustomizationScript(scriptText,
						true, doc, filename[0].ToLower(), filename[2].ToLower());
					if (retVal)
					{
						try
						{
							bool checkOut = true;
							if (sourceControl.IsItemUnderSCC(fi.FullName))
							{
								if (!sourceControl.IsItemCheckedOut(fi.FullName))
								{
									checkOut = sourceControl.CheckOutItem(fi.FullName);
								}
							}

							if (!checkOut)
							{
								MessageBox.Show("Please Check-out Entity Customization file first");
								return;
							}
							XmlWriterSettings xmlSettings = new XmlWriterSettings();
							xmlSettings.Indent = true;
							xmlSettings.NewLineHandling = NewLineHandling.Entitize;
							xmlSettings.NewLineChars = "\n";
							xmlSettings.IndentChars = "\t";
							xmlSettings.OmitXmlDeclaration = true;
							using (XmlWriter tw = XmlWriter.Create(fi.FullName, xmlSettings))
							{
								doc.WriteTo(tw);
								tw.Flush();
							}
						}
						catch { }
					}
				}
			}
		}

        #endregion

	}
}
